package distributedbank.snapshot;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import distributedbank.requests.Request;
import distributedbank.server.Account;

/**
 * Each snapshot instance is owned by each bank branch
 * 
 * @author Bill
 */
public class Snapshots
{
    // each element in the list represents a snapshot
    private Map<Integer, HashMap<Integer, Account>> states = new HashMap<Integer, HashMap<Integer, Account>>();

    // each snapshot can have various requests
    private Map<Integer, List<Request>> channels = new HashMap<Integer, List<Request>>();

    // a list of blocked channels
    private Map<Integer, List<Integer>> blockedChannels = new HashMap<Integer, List<Integer>>();

    /**
     * Get the list of channels for all reqIds, on this bank branch.
     * 
     * @return channels for all reqIds
     */
    public Map<Integer, List<Request>> getChannels() {
        return channels;
    }

    /**
     * Get the blocked channels for all reqIds, on this bank branch.
     * 
     * @return blocked channels for all reqIds
     */
    public Map<Integer, List<Integer>> getBlockedChannels() {
        return blockedChannels;
    }

    /**
     * Store a bank branch's state
     * 
     * @param ssId
     *            snapshot Id
     * @param state
     *            a HashMap<Integer, Account> recording account information in
     *            the bank branch
     */
    public void storeState( int ssId, HashMap<Integer, Account> state ) {
        if( states.containsKey( ssId ) ) {
            System.out.println( "StoreState Error: " + ssId
                    + " is being stored more than once" );
            return;
        }
        states.put( ssId, state );
        channels.put( ssId, new LinkedList<Request>() );
    }

    /**
     * No longer listen to requests from this branch id for this snapshot id
     * 
     * @param ssId
     *            snapshot id
     * @param branchId
     *            the branch we are no longer interested in for this snapshot
     */
    public void stopListening( int ssId, int branchId ) {
        if( !blockedChannels.containsKey( ssId ) ) {
            blockedChannels.put( ssId, new ArrayList<Integer>() );
        }
        blockedChannels.get( ssId ).add( branchId );
    }

    /**
     * Housekeeping
     * 
     * @param ssId
     *            remove all items associated with this ssId EXCEPT
     *            BLOCKEDCHANNEL!!!
     */
    public void cleanup( int ssId ) {
        states.remove( ssId );
        channels.remove( ssId );
    }

    /**
     * Get the state recorded for the Snapshot.
     * 
     * @param ssId
     *            snapshot id
     * @return a HashMap<Integer, Account></br> recording account information in
     *         the bank branch
     */
    public HashMap<Integer, Account> getState( int ssId ) {
        return states.get( ssId );
    }

    /**
     * Get all channel information for a Snapshot Id
     * 
     * @param ssId
     *            snapshot id
     * @return a list of TransferDepositRequests
     */
    public List<Request> getChannel( int ssId ) {
        return channels.get( ssId );
    }
}